package device

import (
	"net"
	"sync"
	"sync/atomic"
)

type Peer struct {
	device       *Device
	publicKey    SecKey
	preSharedKey SecKey
	endpoint     struct {
		sync.RWMutex
		addr *net.UDPAddr
	}
	keypairs                    Keypairs
	handshake                   Handshake
	cookieGenerator             CookieGenerator
	lastHandshakeNano           atomic.Int64 // nano seconds since epoch
	persistentKeepaliveInterval atomic.Uint32
	timers                      struct {
		retransmitHandshake     *Timer
		newHandshake            *Timer
		persistentKeepalive     *Timer
		handshakeAttempts       atomic.Uint32
		needAnotherKeepalive    atomic.Bool
		sentLastMinuteHandshake atomic.Bool
	}
}

func NewPeer() *Peer {
	peer := &Peer{
		endpoint: struct {
			sync.RWMutex
			addr *net.UDPAddr
		}{},
		handshake:       Handshake{},
		cookieGenerator: CookieGenerator{},
	}
	peer.timersInit()
	peer.timersStart()
	return peer
}

func (peer *Peer) updateEndpoint(addr *net.UDPAddr) {
	peer.endpoint.Lock()
	peer.endpoint.addr = addr
	peer.endpoint.Unlock()
}
